#include "buffer.h"
Buffer::Buffer(int initBufferSize)
	:buffer_(initBufferSize)
	,readPos_(0)
	,writePos_(0)
{}
//缓冲区初始位置的指针
char* Buffer::BeginPtr_() 
{
	return &*buffer_.begin(); //对迭代器的第一个位置进行解引用，然后取地址
}
const char* Buffer::BeginPtr_() const 
{
	return &*buffer_.begin();
}
void Buffer::allocateSpace(size_t len) //缓冲区空间不够时扩容
{
	if (writeableBytes() + readBytes() < len) 
	{
		buffer_.resize(writePos_ + len + 1);
	}
	else 
	{
		size_t readable = readableBytes();
		std::copy(BeginPtr_() + readPos_, BeginPtr_() + writePos_, BeginPtr_());
		readPos_ = 0;
		writePos_ = readable;
		assert(readable == readableBytes());
	}
}
//缓存区中可以读取的字节个数
size_t Buffer::readableBytes() const
{
	return writePos_ - readPos_;
}
//缓冲区中可以写入的字节个数
size_t Buffer::writeableBytes() const 
{
	return buffer_.size() - writePos_;
}
//缓冲区中已经读取的字节数
size_t Buffer::readBytes() const 
{
	return readPos_;
}
//获取当前读指针
const char* Buffer::curReadPtr() const 
{
	return BeginPtr_() + readPos_;
}
//获取当前写指针
const char* Buffer::curWritePtrConst() const 
{
	return BeginPtr_() + writePos_;
}
char* Buffer::curWritePtr() 
{
	return BeginPtr_() + writePos_;
}
//更新读指针
void Buffer::updateReadPtr(size_t len) 
{
	assert(len <= readableBytes());
	readPos_ += len;
}
void Buffer::updateReadPtrUntilend(const char* end)//将读指针更新到指定位置
{
	assert(end >= curReadPtr());
	updateReadPtr(end - curReadPtr());
}
//更新写指针
void Buffer::updateWritePtr(size_t len) 
{
	assert(len <= writeableBytes());
	writePos_ += len;
}
//将写指针和读指针初始化
void Buffer::initPtr() 
{
	std::fill(buffer_.begin(), buffer_.end(), 0);
	readPos_ = 0;
	writePos_ = 0;
}

//保证将数据写入缓冲区
void Buffer::ensureWriteable(size_t len) 
{
	if (len > writeableBytes()) 
	{
		allocateSpace(len);
	}
	assert(writeableBytes() >= len);
}
//将数据写到缓冲区
void Buffer::append(const char* str, size_t len) 
{
	assert(str);
	ensureWriteable(len);
	std::copy(str, str + len, curWritePtr());
	updateWritePtr(len);
}
void Buffer::append(const std::string& str) 
{
	append(str.data(), str.length());//data拿到首地址，length拿到长度不包括\0
}
void Buffer::append(const void* data, size_t len) 
{
	assert(data);
	append(static_cast<const char*>(data), len);
}
void Buffer::append(const Buffer& buffer) 
{
	append(buffer.curReadPtr(), buffer.readableBytes());
}
//I/O操作的读与写接口
ssize_t Buffer::readFd(int fd, int* Erron) 
{
	char buff[65535];//暂时的缓冲区
	struct iovec iov[2];
	const size_t writeable = writeableBytes();//buff对象中可用的空间大小
	iov[0].iov_base = BeginPtr_() + writePos_;
	iov[0].iov_len = writeable;
	iov[1].iov_base = buff;
	iov[1].iov_len = sizeof(buff);
	const ssize_t len = readv(fd, iov, 2);
	if (len < 0) 
	{
		//std::cout << "从fd读取数据失败！" << std::endl;
		*Erron = errno;
	}
	else if (static_cast<size_t>(len) <= writeable) 
	{
		writePos_ += len;
	}
	else 
	{
		writePos_ = buffer_.size();//写指针指向末尾
		append(buff, len - writeable);
	}
	return len;
}
ssize_t Buffer::writeFd(int fd, int* Erron) 
{
	size_t readSize = readableBytes();
	ssize_t len = write(fd, curReadPtr(), readSize);
	if (len < 0) 
	{
		*Erron = errno;
		return len;
	}
	readPos_ += len;
	return len;
}

//将缓冲区数据转化为字符串
std::string Buffer::AlltoStr() 
{
	std::string str(curReadPtr(), readableBytes());
	initPtr();
	return str;
}
